package sketch.specs;

import gov.nasa.jpf.util.Files;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;

import sketch.ast.ASTUtils;
import sketch.util.Checker;
import sketch.util.Globals;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class SymbolicFileParsingTest extends TestCase {
	
	public static Test suite() {
		return new TestSuite(SymbolicFileParsingTest.class);
	}
	
//	public void testParsingRemoveFile() throws IOException {
//		String fp = "./tests/sketch/specs/symbolic_remove.txt";
//		SymbolicFileParser p = new SymbolicFileParser(fp);
//		Map<String, List<List<Integer>>> map = p.parseFile();
//		System.out.println(map);
//		
//		assertEquals(340, map.size());
//		
//	}
//	
//	public void testGetSymbolicInt() {
//		String fp = "./subjects/autogen/TreeMapRemoveExpand_Auto_Gen.java";
//		CompilationUnit unit = ASTUtils.astRoot(fp);
//		List<MethodDeclaration> methods = ASTUtils.getAllMethods(unit);
//		assertEquals(340, methods.size());
//		for(MethodDeclaration method : methods) {
//			SymbolicValueVisitor visitor = new SymbolicValueVisitor();
//			method.accept(visitor);
//			Set<MethodInvocation> set = visitor.getSymbolicIntDeclarations();
//			//System.out.println(set.size());
//			assertEquals(1, set.size());
//		}
//	}
	
	public void testReplaceSymbolicValueToGenerateNewTests() throws IOException {
		
		List<MethodDeclaration> allReturnMethods = new LinkedList<MethodDeclaration>();
		
		//read
		String symbolicFile = "./testfiles/sketch/specs/SymbolicRemove.java";
		SymbolicFileParser p = new SymbolicFileParser(symbolicFile);
		Map<String, List<List<Integer>>> map = p.parseFile();
		System.out.println(map);
		assertEquals(340, map.size());
		
		//get all methods
		String fp = "./testfiles/autogen/TreeMapRemoveExpand_Auto_Gen.java";
		CompilationUnit unit = ASTUtils.astRoot(fp);
		List<MethodDeclaration> methods = ASTUtils.getAllMethods(unit);
		assertEquals(340, methods.size());
		for(MethodDeclaration method : methods) {
			MethodDeclaration backup = ASTUtils.deepClone(method);
			SymbolicValueVisitor visitor = new SymbolicValueVisitor();
			method.accept(visitor);
			List<MethodInvocation> l = visitor.getSymbolicIntDeclarationsAsList();
			//System.out.println(set.size());
			assertEquals(1, l.size());
			
			//System.out.println(method.getName());
			String methodName = method.getName().toString();
			int repl_index = methodName.indexOf(sketch.specs.SketchedMethodDeclaration.replic_sep);
			methodName = methodName.substring(0, repl_index) + methodName.substring(repl_index
					+ sketch.specs.SketchedMethodDeclaration.replic_sep.length());
			Checker.checkTrue(map.containsKey(methodName), "The method name: " + methodName + " does not exist!");
			
			List<List<Integer>> intList = map.get(methodName);
			
			SymbolicValueReplacement replacement = new SymbolicValueReplacement(backup, l, intList, null /*be aware just for experiment*/);
			//System.out.println(intList);
			List<MethodDeclaration> afterReplaces = replacement.replaceValues();
			
			Checker.checkTrue(afterReplaces.size() == intList.size(), "The size of intList: " + intList.size() + " !=  the size of after replacement: " + afterReplaces.size());
			
			allReturnMethods.addAll(afterReplaces);
		}
		
		StringBuilder sb = new StringBuilder();
		for(MethodDeclaration m : allReturnMethods) {
			//System.out.println(m);
			sb.append(m.toString());
			sb.append(Globals.lineSep);
		}
		
		System.out.println(allReturnMethods.size());
		Files.writeToFile(sb.toString(), new File("./testfiles/sketch/specs/tmpoutput_afterreplace.txt"));
	}
}
